﻿using System;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using LAPI.Core;

namespace LAPI.Data.Model
{
    /// <summary>
    /// Modelo de la tabla 'Reservas'
    /// </summary>
    public class Reserva
    {
        #region Model
        //PK
        [DataType(DataType.Text)]
        [Display(Name = "#")]
        public Int32 IdReserva { get; set; }
        //FK
        public Int32 IdUsuario { get; set; }
        public Int32 IdDeportesPista { get; set; }

        public String user { get; set; }
        public String centroDeportivo { get; set; }
        public String pista { get; set; }
        public String deporte { get; set; }
        public String color { get; set; }
       
        public DateTime horaInicio { get; set; }
        public DateTime horaFinal { get; set; }

        public Boolean luz { get; set; }
        public Boolean activo { get; set; }
        public Double importe { get; set; }
        #endregion 

        #region Data Helper
        public const String Table = "RESERVAS";
        public const String Tables = "RESERVAS, CENTRODEPORTIVO, PISTA, DEPORTES, DEPORTESPISTA, USUARIO";
        public const String Columns = "RESERVAS.ID_RESERVAS, RESERVAS.Id_usuario, RESERVAS.id_deportespista, RESERVAS.hora_ini, RESERVAS.hora_fin, RESERVAS.activo, RESERVAS.luz, DEPORTES.descripcion deporte, DEPORTES.color color, CENTRODEPORTIVO.descripcion centro, PISTA.descripcion pista, USUARIO.usuario, RESERVAS.importe";
        #endregion

        #region Insert Helper
        /// <summary>
        /// Crea la cadena con todas las columnas necesarias en una sentencia insert.
        /// </summary>
        /// <returns>String con la cadena</returns>
        public String ToInsertColumns()
        {
            return "id_usuario, id_deportespista, hora_ini, hora_fin, activo, luz, importe";
        }

        /// <summary>
        /// Crea una cadena con todos los valores a insertar en una sentencia insert.
        /// </summary>
        /// <returns>String con la cadena</returns>
        public String ToInsertValues()
        {
            StringBuilder sentence = new StringBuilder();
            sentence.Append(this.IdUsuario);
            sentence.Append(",");
            sentence.Append(this.IdDeportesPista);
            sentence.Append(",'");
            sentence.Append(this.horaInicio.ToString("yyyy-MM-dd HH:mm"));
            sentence.Append("','");
            sentence.Append(this.horaFinal.ToString("yyyy-MM-dd HH:mm"));
            sentence.Append("',1,");
            sentence.Append(this.luz ? 1 : 0);
            sentence.Append(",'");
            sentence.Append(this.importe.ToString().Replace(',', '.'));
            sentence.Append("'");

            return sentence.ToString();
        }
        #endregion

        #region Update Helper 
        /// <summary>
        /// Crea la cadena 'SET x1=y1, x2=y2' de una sentencia update.
        /// <p>Actualiza los siguientes datos del modelo:</p>
        /// <ul>
        /// <li>horaInicio</li>
        /// <li>horaFinal</li>
        /// <li>luz</li>
        /// <li>importe</li>
        /// </ul>
        /// </summary>
        /// <returns>String con la cadena</returns>
        public String ToUpdate()
        {
            StringBuilder sentence = new StringBuilder();
            sentence.Append("importe = ");
            sentence.Append(this.importe.ToString().Replace(',', '.'));
            sentence.Append(",");
            sentence.Append("hora_ini = '");
            sentence.Append(this.horaInicio);
            sentence.Append("',");
            sentence.Append("hora_fin = '");
            sentence.Append(this.horaFinal);
            sentence.Append("',");
            sentence.Append("luz = ");
            sentence.Append(this.luz ? 1 : 0);
            sentence.Append("");
            return sentence.ToString();
        }

        /// <summary>
        /// Crea la cadena 'SET x1=y1, x2=y2' de una sentencia update.
        /// <p>Actualiza los siguientes datos del modelo:</p>
        /// <ul>
        /// <li>Activo</li>
        /// </ul>
        /// </summary>
        /// <returns>String con la cadena</returns>
        public String ToUpdateEstado()
        {
            StringBuilder sentence = new StringBuilder();
            sentence.Append("Activo = '");
            sentence.Append(this.activo ? 1 : 0);
            sentence.Append("'");

            return sentence.ToString();
        }
        #endregion

        /// <summary>
        /// Método para convertir un Dataset en el modelo.
        /// </summary>
        /// <param name="response">Dataset obtenido en una consulta</param>
        /// <returns>Colección con los modelos obtenidos en la conversión</returns>
        public static System.Collections.Generic.List<LAPI.Data.Model.Reserva> toModel(System.Data.DataSet response)
        {
            System.Collections.Generic.List<LAPI.Data.Model.Reserva> result = new System.Collections.Generic.List<Data.Model.Reserva>();

            foreach (System.Data.DataRow item in response.Tables[0].Rows)
            {
                LAPI.Data.Model.Reserva model = new Data.Model.Reserva();
                model.IdReserva = Convert.ToInt32(item["id_reservas"].ToString());
                model.IdUsuario = Convert.ToInt32(item["id_usuario"].ToString());                
                model.IdDeportesPista = Convert.ToInt32(item["id_deportespista"].ToString());

                model.horaInicio = Convert.ToDateTime(item["hora_ini"].ToString());
                model.horaFinal = Convert.ToDateTime(item["hora_fin"].ToString());

                model.activo = Convert.ToBoolean(item["activo"].ToString());
                model.luz = Convert.ToBoolean(item["luz"].ToString());

                model.deporte = item["deporte"].ToString();
                model.centroDeportivo = item["centro"].ToString();
                model.pista = item["pista"].ToString();
                model.user = item["usuario"].ToString();
                model.color = item["color"].ToString();

                model.importe = Convert.ToDouble(item["importe"].ToString());  

                result.Add(model);
            }

            return result;
        }

        /// <summary>
        /// Método para convertir una colección del modelo, en un JSON
        /// </summary>
        /// <param name="models">colección del modelo</param>
        /// <returns>JSON de la colección</returns>
        public static String toJson(System.Collections.Generic.List<LAPI.Data.Model.Reserva> models)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            System.IO.StringWriter sw = new System.IO.StringWriter(sb);

            using (Newtonsoft.Json.JsonWriter jsonWriter = new Newtonsoft.Json.JsonTextWriter(sw))
            {
                jsonWriter.Formatting = Newtonsoft.Json.Formatting.Indented;
                jsonWriter.WriteStartObject();
                jsonWriter.WritePropertyName("items");
                jsonWriter.WriteStartArray();

                foreach (var item in models)
                {
                    jsonWriter.WriteStartObject();
                    jsonWriter.WritePropertyName("id");
                    jsonWriter.WriteValue(item.IdReserva);
                    jsonWriter.WritePropertyName("data");
                    jsonWriter.WriteValue(item.deporte);
                    jsonWriter.WritePropertyName("dateStart");
                    jsonWriter.WriteValue(item.horaInicio.ToString("yyyy-MM-dd HH:mm"));
                    jsonWriter.WritePropertyName("dateEnd");
                    jsonWriter.WriteValue(item.horaFinal.ToString("yyyy-MM-dd HH:mm"));
                    jsonWriter.WritePropertyName("color");
                    jsonWriter.WriteValue(item.color);
                    jsonWriter.WriteEndObject();
                }
                jsonWriter.WriteEndArray();
                jsonWriter.WriteEndObject();
            }

            return sb.ToString();
        }

        /// <summary>
        /// Método para convertir una colección del modelo, en un JSON
        /// </summary>
        /// <param name="models">colección del modelo de reserva</param>
        /// <param name="auxModel">modelo de pista </param>
        /// <returns>JSON de la colección</returns>
        public static String toJson(System.Collections.Generic.List<LAPI.Data.Model.Reserva> models, LAPI.Data.Model.Pista auxModel)
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            System.IO.StringWriter sw = new System.IO.StringWriter(sb);

            using (Newtonsoft.Json.JsonWriter jsonWriter = new Newtonsoft.Json.JsonTextWriter(sw))
            {
                jsonWriter.Formatting = Newtonsoft.Json.Formatting.Indented;
                jsonWriter.WriteStartObject();
                jsonWriter.WritePropertyName("items");
                jsonWriter.WriteStartArray();

                foreach (var item in models)
                {
                    jsonWriter.WriteStartObject();
                    jsonWriter.WritePropertyName("id");
                    jsonWriter.WriteValue(item.IdReserva);
                    jsonWriter.WritePropertyName("data");
                    jsonWriter.WriteValue(item.deporte);
                    jsonWriter.WritePropertyName("dateStart");
                    jsonWriter.WriteValue(item.horaInicio.ToString("yyyy-MM-dd HH:mm"));
                    jsonWriter.WritePropertyName("dateEnd");
                    jsonWriter.WriteValue(item.horaFinal.ToString("yyyy-MM-dd HH:mm"));
                    jsonWriter.WritePropertyName("color");
                    jsonWriter.WriteValue(item.color);
                    jsonWriter.WriteEndObject();
                }
                jsonWriter.WriteEndArray();

                jsonWriter.WritePropertyName("horaApertura");
                jsonWriter.WriteValue(auxModel.tHoraInicio.ToString("yyyy-MM-dd HH:mm"));
                jsonWriter.WritePropertyName("horaCierre");
                jsonWriter.WriteValue(auxModel.tHoraFinal.ToString("yyyy-MM-dd HH:mm"));
                jsonWriter.WriteEndObject();
            }

            return sb.ToString();
        }

        public override String ToString()
        {
            return "[Reserva]{IdReserva:" + IdReserva +
                ",IdUsuario:" + IdUsuario +
                ",IdDeportesPista:" + IdDeportesPista +
                ",horaInicio:" + horaInicio +
                ",horaFinal:" + horaFinal +
                ",luz:" + luz +
                "}";
        }
    }
}
